home *** CD-ROM | disk | FTP | other *** search
/ Clickx 47 / Clickx 47.iso / assets / software / Miro_Installer.exe / Miro_Downloader.exe / iconcache.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2008-01-10  |  9.5 KB  |  357 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.5)
  3.  
  4. import item
  5. import os
  6. import threading
  7. import httpclient
  8. from fasttypes import LinkedList
  9. from eventloop import asIdle, addIdle, addTimeout
  10. from download_utils import nextFreeFilename, getFileURLPath
  11. from util import unicodify, call_command
  12. from platformutils import unicodeToFilename
  13. import config
  14. import prefs
  15. import time
  16. import views
  17. import random
  18. import imageresize
  19. RUNNING_MAX = 3
  20.  
  21. def clearOrphans():
  22.     knownIcons = set()
  23.     for item in views.items:
  24.         if item.iconCache and item.iconCache.filename:
  25.             knownIcons.add(os.path.normcase(item.iconCache.filename))
  26.             for resized in item.iconCache.resized_filenames.values():
  27.                 knownIcons.add(os.path.normcase(resized))
  28.             
  29.     
  30.     for feed in views.feeds:
  31.         if feed.iconCache and feed.iconCache.filename:
  32.             knownIcons.add(os.path.normcase(feed.iconCache.filename))
  33.             for resized in feed.iconCache.resized_filenames.values():
  34.                 knownIcons.add(os.path.normcase(resized))
  35.             
  36.     
  37.     cachedir = config.get(prefs.ICON_CACHE_DIRECTORY)
  38.  
  39.  
  40. class IconCacheUpdater:
  41.     
  42.     def __init__(self):
  43.         self.idle = LinkedList()
  44.         self.vital = LinkedList()
  45.         self.runningCount = 0
  46.         self.inShutdown = False
  47.  
  48.     
  49.     def requestUpdate(self, item, is_vital = False):
  50.         if is_vital:
  51.             item.dbItem.confirmDBThread()
  52.             if item.filename and os.access(item.filename, os.R_OK):
  53.                 is_vital = False
  54.             
  55.         
  56.         if self.runningCount < RUNNING_MAX:
  57.             addIdle(item.requestIcon, 'Icon Request')
  58.             self.runningCount += 1
  59.         elif is_vital:
  60.             self.vital.prepend(item)
  61.         else:
  62.             self.idle.prepend(item)
  63.  
  64.     requestUpdate = asIdle(requestUpdate)
  65.     
  66.     def updateFinished(self):
  67.         if self.inShutdown:
  68.             self.runningCount -= 1
  69.             return None
  70.         
  71.         if len(self.vital) > 0:
  72.             item = self.vital.pop()
  73.         elif len(self.idle) > 0:
  74.             item = self.idle.pop()
  75.         else:
  76.             self.runningCount -= 1
  77.             return None
  78.         addIdle(item.requestIcon, 'Icon Request')
  79.  
  80.     
  81.     def clearVital(self):
  82.         self.vital = LinkedList()
  83.  
  84.     clearVital = asIdle(clearVital)
  85.     
  86.     def shutdown(self):
  87.         self.inShutdown = True
  88.  
  89.     shutdown = asIdle(shutdown)
  90.  
  91. iconCacheUpdater = IconCacheUpdater()
  92.  
  93. class IconCache:
  94.     
  95.     def __init__(self, dbItem, is_vital = False):
  96.         self.etag = None
  97.         self.modified = None
  98.         self.filename = None
  99.         self.resized_filenames = { }
  100.         self.url = None
  101.         self.updated = False
  102.         self.updating = False
  103.         self.needsUpdate = False
  104.         self.dbItem = dbItem
  105.         self.removed = False
  106.         self.requestUpdate(is_vital = is_vital)
  107.  
  108.     
  109.     def iconChanged(self, needsSave = True):
  110.         
  111.         try:
  112.             self.dbItem.iconChanged(needsSave = needsSave)
  113.         except:
  114.             self.dbItem.signalChange(needsSave = needsSave)
  115.  
  116.  
  117.     
  118.     def remove(self):
  119.         self.removed = True
  120.         self._removeFile(self.filename)
  121.         imageresize.removeResizedFiles(self.resized_filenames)
  122.  
  123.     
  124.     def reset(self):
  125.         self._removeFile(self.filename)
  126.         imageresize.removeResizedFiles(self.resized_filenames)
  127.         self.filename = None
  128.         self.resized_filenamed = { }
  129.         self.url = None
  130.         self.etag = None
  131.         self.modified = None
  132.         self.removed = False
  133.         self.updated = False
  134.         self.updating = False
  135.         self.needsUpdate = False
  136.         self.iconChanged()
  137.  
  138.     
  139.     def _removeFile(self, filename):
  140.         
  141.         try:
  142.             os.remove(filename)
  143.         except:
  144.             pass
  145.  
  146.  
  147.     
  148.     def errorCallback(self, url, error = None):
  149.         self.dbItem.confirmDBThread()
  150.         if self.removed:
  151.             iconCacheUpdater.updateFinished()
  152.             return None
  153.         
  154.         if self.url != url:
  155.             self.url = url
  156.             self.etag = None
  157.             self.modified = None
  158.             self.iconChanged()
  159.         
  160.         self.updating = False
  161.         if self.needsUpdate:
  162.             self.needsUpdate = False
  163.             self.requestUpdate()
  164.         elif error is not None:
  165.             addTimeout(3600, self.requestUpdate, 'Thumbnail request for %s' % url)
  166.         else:
  167.             self.updated = True
  168.         iconCacheUpdater.updateFinished()
  169.  
  170.     
  171.     def updateIconCache(self, url, info):
  172.         self.dbItem.confirmDBThread()
  173.         if self.removed:
  174.             iconCacheUpdater.updateFinished()
  175.             return None
  176.         
  177.         needsSave = False
  178.         needsChange = False
  179.         if (info == None or info['status'] != 304) and info['status'] != 200:
  180.             self.errorCallback(url)
  181.             return None
  182.         
  183.         
  184.         try:
  185.             if info['status'] == 304:
  186.                 self.updated = True
  187.                 return None
  188.             
  189.             needsChange = True
  190.             if self.filename and not os.access(self.filename, os.R_OK | os.W_OK):
  191.                 self.filename = None
  192.                 seedsSave = True
  193.             
  194.             cachedir = config.get(prefs.ICON_CACHE_DIRECTORY)
  195.             
  196.             try:
  197.                 os.makedirs(cachedir)
  198.             except:
  199.                 pass
  200.  
  201.             
  202.             try:
  203.                 if self.filename:
  204.                     tmp_filename = self.filename + '.part'
  205.                 else:
  206.                     tmp_filename = os.path.join(cachedir, info['filename']) + '.part'
  207.                 tmp_filename = nextFreeFilename(tmp_filename)
  208.                 output = file(tmp_filename, 'wb')
  209.                 output.write(info['body'])
  210.                 output.close()
  211.             except IOError:
  212.                 
  213.                 try:
  214.                     os.remove(tmp_filename)
  215.                 except:
  216.                     pass
  217.  
  218.                 return None
  219.  
  220.             if self.filename == None:
  221.                 parts = unicodify(info['filename']).split('.')
  222.                 uid = u'%08d' % (random.randint(0, 99999999),)
  223.                 if len(parts) == 1:
  224.                     parts.append(uid)
  225.                 else:
  226.                     parts[-1:-1] = [
  227.                         uid]
  228.                 self.filename = u'.'.join(parts)
  229.                 self.filename = unicodeToFilename(self.filename, cachedir)
  230.                 self.filename = os.path.join(cachedir, self.filename)
  231.                 self.filename = nextFreeFilename(self.filename)
  232.                 needsSave = True
  233.             
  234.             self._removeFile(self.filename)
  235.             
  236.             try:
  237.                 os.rename(tmp_filename, self.filename)
  238.             except:
  239.                 self.filename = None
  240.                 needsSave = True
  241.  
  242.             self.resizeIcon()
  243.             if info.has_key('etag'):
  244.                 etag = unicodify(info['etag'])
  245.             else:
  246.                 etag = None
  247.             if info.has_key('modified'):
  248.                 modified = unicodify(info['modified'])
  249.             else:
  250.                 modified = None
  251.             if self.etag != etag:
  252.                 needsSave = True
  253.                 self.etag = etag
  254.             
  255.             if self.modified != modified:
  256.                 needsSave = True
  257.                 self.modified = modified
  258.             
  259.             if self.url != url:
  260.                 needsSave = True
  261.                 self.url = url
  262.             
  263.             self.updated = True
  264.         finally:
  265.             if needsChange:
  266.                 self.iconChanged(needsSave = needsSave)
  267.             
  268.             self.updating = False
  269.             if self.needsUpdate:
  270.                 self.needsUpdate = False
  271.                 self.requestUpdate()
  272.             
  273.             iconCacheUpdater.updateFinished()
  274.  
  275.  
  276.     
  277.     def requestIcon(self):
  278.         if self.removed:
  279.             iconCacheUpdater.updateFinished()
  280.             return None
  281.         
  282.         self.dbItem.confirmDBThread()
  283.         if self.updating:
  284.             self.needsUpdate = True
  285.             iconCacheUpdater.updateFinished()
  286.             return None
  287.         
  288.         
  289.         try:
  290.             url = self.dbItem.getThumbnailURL()
  291.         except:
  292.             url = self.url
  293.  
  294.         if self.updated and url == self.url:
  295.             iconCacheUpdater.updateFinished()
  296.             return None
  297.         
  298.         self.updating = True
  299.         if url is None and url.startswith(u'/') or url.startswith(u'file://'):
  300.             self.errorCallback(url)
  301.             return None
  302.         
  303.         if url == self.url and self.filename and os.access(self.filename, os.R_OK):
  304.             None(None, ((httpclient.grabURL, url), (lambda info: self.updateIconCache(url, info))), (lambda error: self.errorCallback(url, error)), etag = self.etag, modified = self.modified)
  305.         else:
  306.             None(None, ((httpclient.grabURL, url), (lambda info: self.updateIconCache(url, info))), (lambda error: self.errorCallback(url, error)))
  307.  
  308.     
  309.     def requestUpdate(self, is_vital = False):
  310.         if hasattr(self, 'updating') and hasattr(self, 'dbItem'):
  311.             if self.removed:
  312.                 return None
  313.             
  314.             iconCacheUpdater.requestUpdate(self, is_vital = is_vital)
  315.         
  316.  
  317.     
  318.     def onRestore(self):
  319.         self.removed = False
  320.         self.updated = False
  321.         self.updating = False
  322.         self.needsUpdate = False
  323.         self.requestUpdate()
  324.  
  325.     
  326.     def isValid(self):
  327.         self.dbItem.confirmDBThread()
  328.         if self.filename:
  329.             pass
  330.         return os.path.exists(self.filename)
  331.  
  332.     
  333.     def getFilename(self):
  334.         self.dbItem.confirmDBThread()
  335.         if self.url and self.url.startswith(u'file://'):
  336.             return getFileURLPath(self.url)
  337.         elif self.url and self.url.startswith(u'/'):
  338.             return self.url
  339.         else:
  340.             return self.filename
  341.  
  342.     
  343.     def getResizedFilename(self, width, height):
  344.         
  345.         try:
  346.             return imageresize.getImage(self.resized_filenames, width, height)
  347.         except KeyError:
  348.             return self.getFilename()
  349.  
  350.  
  351.     
  352.     def resizeIcon(self):
  353.         imageresize.removeResizedFiles(self.resized_filenames)
  354.         self.resized_filenames = imageresize.multiResizeImage(self.filename, self.dbItem.ICON_CACHE_SIZES)
  355.  
  356.  
  357.